package com.example.demo.config;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class JWTTokenUtil {
    //自定义key名
    //创建时间key 自定义key名
    private static final String CLAIM_KEY_CREATED="created";


    //签名密钥
    @Value("${jwt.secret}")
    private String secret;
    //过期时间
    @Value("${jwt.expiration}")
    private Long expiration;
    @Value("${jwt.tokenHead}")
    private String tokenHead;

    public  String generateToken(UserDetails userDetails)
    {
        Map<String,Object> claims=new HashMap<>();
        claims.put(Claims.SUBJECT,userDetails.getUsername());
        claims.put(CLAIM_KEY_CREATED,new Date());
        return generateToken(claims);
    }

    //负载分为 头部 负载  以及签证
    public String generateToken(Map<String,Object>claims)
    {
        System.out.println(secret);
        return tokenHead+Jwts.builder().
                setClaims(claims).//添加荷载
                setExpiration(generateExpirationDate()).//添加失效时间
                signWith(SignatureAlgorithm.HS256,secret).//添加签名方式
                compact();
    }


    //从Token中获取登录用户名
    public String getUsernameFromToken(String token)
    {
        String username;
        try {
            Claims claims= Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
            username=claims.getSubject();
        }
        catch (Exception e)
        {
            System.out.println(e);
            username=null;
        }
        return  username;
    }

    private Date generateExpirationDate()
    {
        return new Date(System.currentTimeMillis()+expiration*1000);
    }

    //验证token是否有效
    public  boolean validateToken(String token,UserDetails userDetails)
    {
        String username=getUsernameFromToken(token);
        return username.equals(userDetails.getUsername())&&isTokenExpired(token);
    }

    //判断Token是否超时
    private boolean isTokenExpired(String token)
    {
        Claims claims= Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
        Date expireDate =claims.getExpiration();
        return expireDate.after(new Date());
    }

    //判断token是否可以刷新
    public boolean canRefresh(String token)
    {
        return !isTokenExpired(token);
    }

    //刷新Token
    public  String refreshToken(String token)
    {
        Claims claims= Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
        claims.put(CLAIM_KEY_CREATED,new Date());
        return generateToken(claims);
    }
}
